﻿2026-05-16T02:28:13.2735515Z ##[group]Run pnpm verify:phase-4
2026-05-16T02:28:13.2735869Z [36;1mpnpm verify:phase-4[0m
2026-05-16T02:28:13.2771731Z shell: /usr/bin/bash -e {0}
2026-05-16T02:28:13.2771985Z env:
2026-05-16T02:28:13.2772236Z   PNPM_HOME: /home/runner/setup-pnpm/node_modules/.bin
2026-05-16T02:28:13.2772575Z   SKIP_PHASE_3_CARRYOVER: 1
2026-05-16T02:28:13.2772819Z   SKIP_TRACE_CHECK: 1
2026-05-16T02:28:13.2773029Z ##[endgroup]
2026-05-16T02:28:13.5878594Z 
2026-05-16T02:28:13.5889971Z > rebno@0.0.0 verify:phase-4 /home/runner/work/rebno/rebno
2026-05-16T02:28:13.5894878Z > node scripts/verify-phase-4.mjs
2026-05-16T02:28:13.5906361Z 
2026-05-16T02:28:13.6274261Z 
2026-05-16T02:28:13.6275411Z === Workspace: typecheck ===
2026-05-16T02:28:13.6276493Z >>> pnpm -r typecheck
2026-05-16T02:28:13.9621875Z Scope: 5 of 6 workspace projects
2026-05-16T02:28:13.9680488Z packages/db typecheck$ tsc --noEmit
2026-05-16T02:28:13.9689866Z packages/game-logic typecheck$ tsc --noEmit
2026-05-16T02:28:16.7187101Z packages/game-logic typecheck: Done
2026-05-16T02:28:16.7195339Z packages/protocol typecheck$ tsc --noEmit
2026-05-16T02:28:19.1708694Z packages/db typecheck: Done
2026-05-16T02:28:20.4507459Z packages/protocol typecheck: Done
2026-05-16T02:28:20.4516612Z apps/client typecheck$ tsc --noEmit
2026-05-16T02:28:20.4520948Z apps/server typecheck$ tsc --noEmit
2026-05-16T02:28:33.3102330Z apps/client typecheck: Done
2026-05-16T02:28:34.1317833Z apps/server typecheck: Done
2026-05-16T02:28:34.1420970Z 
2026-05-16T02:28:34.1421652Z === Lint: protocol-sync ===
2026-05-16T02:28:34.1422719Z >>> pnpm lint:protocol-sync
2026-05-16T02:28:34.4584914Z 
2026-05-16T02:28:34.4586169Z > rebno@0.0.0 lint:protocol-sync /home/runner/work/rebno/rebno
2026-05-16T02:28:34.4587429Z > node tools/scripts/lint-protocol-sync.mjs
2026-05-16T02:28:34.4588359Z 
2026-05-16T02:28:34.4901106Z lint-protocol-sync: OK
2026-05-16T02:28:34.5031643Z 
2026-05-16T02:28:34.5032543Z === Lint: game-logic-purity ===
2026-05-16T02:28:34.5033477Z >>> pnpm lint:game-logic-purity
2026-05-16T02:28:34.8271712Z 
2026-05-16T02:28:34.8272814Z > rebno@0.0.0 lint:game-logic-purity /home/runner/work/rebno/rebno
2026-05-16T02:28:34.8274120Z > node tools/scripts/lint-game-logic-purity.mjs
2026-05-16T02:28:34.8274807Z 
2026-05-16T02:28:34.8606526Z lint-game-logic-purity: OK (8 file(s) clean)
2026-05-16T02:28:34.8751825Z 
2026-05-16T02:28:34.8752614Z === Lint: better-auth-schema-sync ===
2026-05-16T02:28:34.8753730Z >>> pnpm lint:better-auth-schema-sync
2026-05-16T02:28:35.1932211Z 
2026-05-16T02:28:35.1933430Z > rebno@0.0.0 lint:better-auth-schema-sync /home/runner/work/rebno/rebno
2026-05-16T02:28:35.1934995Z > node tools/scripts/lint-better-auth-schema-sync.mjs
2026-05-16T02:28:35.1935728Z 
2026-05-16T02:28:36.9485519Z lint-better-auth-schema-sync: OK
2026-05-16T02:28:36.9606769Z 
2026-05-16T02:28:36.9607686Z === Lint: rate-limit-budgets ===
2026-05-16T02:28:36.9608858Z >>> pnpm lint:rate-limit-budgets
2026-05-16T02:28:37.2832644Z 
2026-05-16T02:28:37.2833830Z > rebno@0.0.0 lint:rate-limit-budgets /home/runner/work/rebno/rebno
2026-05-16T02:28:37.2835162Z > node tools/scripts/lint-rate-limit-budgets.mjs
2026-05-16T02:28:37.2835856Z 
2026-05-16T02:28:37.3132182Z lint-rate-limit-budgets: OK (5 D-22 budgets locked)
2026-05-16T02:28:37.3259522Z 
2026-05-16T02:28:37.3260326Z === Lint: no-clipboard-rce ===
2026-05-16T02:28:37.3261156Z >>> pnpm lint:no-clipboard-rce
2026-05-16T02:28:37.6433669Z 
2026-05-16T02:28:37.6435072Z > rebno@0.0.0 lint:no-clipboard-rce /home/runner/work/rebno/rebno
2026-05-16T02:28:37.6436421Z > node tools/scripts/lint-no-clipboard-rce.mjs
2026-05-16T02:28:37.6437110Z 
2026-05-16T02:28:37.6813319Z lint-no-clipboard-rce: OK (22 file(s) clean)
2026-05-16T02:28:37.6939983Z 
2026-05-16T02:28:37.6940694Z === Lint: room-layout ===
2026-05-16T02:28:37.6941516Z >>> pnpm lint:room-layout
2026-05-16T02:28:38.0253594Z 
2026-05-16T02:28:38.0254709Z > rebno@0.0.0 lint:room-layout /home/runner/work/rebno/rebno
2026-05-16T02:28:38.0256116Z > node tools/scripts/lint-room-layout.mjs
2026-05-16T02:28:38.0257630Z 
2026-05-16T02:28:38.0644079Z lint-room-layout: OK
2026-05-16T02:28:38.0772109Z 
2026-05-16T02:28:38.0772779Z === ADR 0004 lint ===
2026-05-16T02:28:38.0773490Z >>> pnpm lint:adr:0004
2026-05-16T02:28:38.3970182Z 
2026-05-16T02:28:38.3971302Z > rebno@0.0.0 lint:adr:0004 /home/runner/work/rebno/rebno
2026-05-16T02:28:38.3974494Z > node tools/asset-catalog/scripts/lint-adr.mjs docs/adr/0004-room-hot-reload.md --no-matrix
2026-05-16T02:28:38.3975196Z 
2026-05-16T02:28:38.4289646Z OK: ADR docs/adr/0004-room-hot-reload.md validated (no-matrix mode — Michael Nygard sections present)
2026-05-16T02:28:38.4411640Z 
2026-05-16T02:28:38.4412431Z === Drizzle: emit-check ===
2026-05-16T02:28:38.4413650Z >>> pnpm db:emit-check
2026-05-16T02:28:38.7800698Z 
2026-05-16T02:28:38.7804838Z > rebno@0.0.0 db:emit-check /home/runner/work/rebno/rebno
2026-05-16T02:28:38.7809729Z > pnpm -C packages/db exec drizzle-kit generate && node -e "require('fs').copyFileSync('packages/db/migrations/0001_baseline.sql','docs/extracted-server/0001_baseline.sql')" && git diff --exit-code packages/db/migrations/0001_baseline.sql docs/extracted-server/0001_baseline.sql
2026-05-16T02:28:38.7811651Z 
2026-05-16T02:28:39.2531410Z No config path provided, using default 'drizzle.config.ts'
2026-05-16T02:28:39.2535306Z Reading config file '/home/runner/work/rebno/rebno/packages/db/drizzle.config.ts'
2026-05-16T02:28:39.7041831Z 8 tables
2026-05-16T02:28:39.7045609Z accounts 8 columns 1 indexes 0 fks
2026-05-16T02:28:39.7048529Z audit_log 6 columns 0 indexes 2 fks
2026-05-16T02:28:39.7049108Z characters 9 columns 0 indexes 1 fks
2026-05-16T02:28:39.7049728Z inventory_items 4 columns 0 indexes 1 fks
2026-05-16T02:28:39.7050444Z legacy_credentials_staging 6 columns 0 indexes 0 fks
2026-05-16T02:28:39.7051178Z message_board_replies 5 columns 0 indexes 2 fks
2026-05-16T02:28:39.7051851Z message_board_topics 7 columns 0 indexes 1 fks
2026-05-16T02:28:39.7052478Z sessions 5 columns 0 indexes 1 fks
2026-05-16T02:28:39.7052805Z 
2026-05-16T02:28:39.7053436Z No schema changes, nothing to migrate 😴
2026-05-16T02:28:40.3298598Z 
2026-05-16T02:28:40.3302946Z === Drizzle: schema-sync ===
2026-05-16T02:28:40.3305384Z >>> pnpm lint:schema-sync
2026-05-16T02:28:40.6483071Z 
2026-05-16T02:28:40.6484179Z > rebno@0.0.0 lint:schema-sync /home/runner/work/rebno/rebno
2026-05-16T02:28:40.6489709Z > node -e "const a=require('fs').readFileSync('packages/db/migrations/0001_baseline.sql');const b=require('fs').readFileSync('docs/extracted-server/0001_baseline.sql');if(Buffer.compare(a,b)!==0){console.error('docs/extracted-server/0001_baseline.sql out of sync with packages/db/migrations/0001_baseline.sql');process.exit(1)}console.log('OK')"
2026-05-16T02:28:40.6491970Z 
2026-05-16T02:28:40.6765561Z OK
2026-05-16T02:28:40.6891672Z 
2026-05-16T02:28:40.6892685Z === Drizzle: source-comments ===
2026-05-16T02:28:40.6893994Z >>> pnpm lint:source-comments
2026-05-16T02:28:41.0120446Z 
2026-05-16T02:28:41.0121365Z > rebno@0.0.0 lint:source-comments /home/runner/work/rebno/rebno
2026-05-16T02:28:41.0122687Z > pnpm -C packages/db run lint:source-comments
2026-05-16T02:28:41.0123304Z 
2026-05-16T02:28:41.3360909Z 
2026-05-16T02:28:41.3362139Z > @rebno/db@0.1.0 lint:source-comments /home/runner/work/rebno/rebno/packages/db
2026-05-16T02:28:41.3363584Z > node scripts/check-source-comments.mjs
2026-05-16T02:28:41.3364168Z 
2026-05-16T02:28:41.3699929Z check-source-comments: OK (50 columns, all SOURCE-cited)
2026-05-16T02:28:41.3939295Z 
2026-05-16T02:28:41.3940203Z === Workspace: test ===
2026-05-16T02:28:41.3941121Z >>> pnpm -r test
2026-05-16T02:28:41.7255467Z Scope: 5 of 6 workspace projects
2026-05-16T02:28:41.7314614Z packages/db test$ vitest run
2026-05-16T02:28:41.7323696Z packages/game-logic test$ vitest run
2026-05-16T02:28:42.2647341Z packages/db test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/db[39m
2026-05-16T02:28:42.2679941Z packages/game-logic test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/game-logic[39m
2026-05-16T02:28:42.7230279Z packages/game-logic test:  [32m✓[39m test/step-bno-fidelity.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T02:28:42.9826181Z packages/game-logic test:  [32m✓[39m test/wall-slide.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:28:43.2223441Z packages/game-logic test:  [32m✓[39m test/golden.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-16T02:28:43.3459920Z packages/db test:  [32m✓[39m tests/promotion.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T02:28:43.4798869Z packages/game-logic test:  [32m✓[39m test/walkable-edge.test.ts [2m([22m[2m1 test[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:28:43.6230631Z packages/db test:  [32m✓[39m tests/save-format-traceability.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-16T02:28:43.7127265Z packages/game-logic test:  [32m✓[39m test/movement-constants.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T02:28:43.9487818Z packages/game-logic test:  [32m✓[39m test/sprite-state-machine.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T02:28:44.1720517Z packages/game-logic test:  [32m✓[39m test/navi-mask-bbox.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:28:44.4236746Z packages/game-logic test:  [32m✓[39m test/platform-cycle.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T02:28:44.4725677Z packages/db test:  [32m✓[39m tests/schema-shape.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 13[2mms[22m[39m
2026-05-16T02:28:44.4860003Z packages/db test: [2m Test Files [22m [1m[32m3 passed[39m[22m[90m (3)[39m
2026-05-16T02:28:44.4879552Z packages/db test: [2m      Tests [22m [1m[32m22 passed[39m[22m[90m (22)[39m
2026-05-16T02:28:44.4919205Z packages/db test: [2m   Start at [22m 02:28:42
2026-05-16T02:28:44.4936153Z packages/db test: [2m   Duration [22m 2.21s[2m (transform 202ms, setup 0ms, import 1.49s, tests 35ms, environment 1ms)[22m
2026-05-16T02:28:44.5216345Z packages/db test: Done
2026-05-16T02:28:44.5237268Z packages/protocol test$ vitest run
2026-05-16T02:28:44.6663626Z packages/game-logic test:  [32m✓[39m test/accumulator.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T02:28:44.9105557Z packages/game-logic test:  [32m✓[39m test/run-speed.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:28:45.0892924Z packages/protocol test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/packages/protocol[39m
2026-05-16T02:28:45.1680526Z packages/game-logic test:  [32m✓[39m test/rng.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T02:28:45.1762676Z packages/game-logic test: [2m Test Files [22m [1m[32m11 passed[39m[22m[90m (11)[39m
2026-05-16T02:28:45.1779453Z packages/game-logic test: [2m      Tests [22m [1m[32m55 passed[39m[22m[90m (55)[39m
2026-05-16T02:28:45.1780703Z packages/game-logic test: [2m   Start at [22m 02:28:42
2026-05-16T02:28:45.1799733Z packages/game-logic test: [2m   Duration [22m 2.89s[2m (transform 258ms, setup 0ms, import 510ms, tests 97ms, environment 2ms)[22m
2026-05-16T02:28:45.2193127Z packages/game-logic test: Done
2026-05-16T02:28:45.4727674Z packages/protocol test:  [32m✓[39m test/codec.test.ts [2m([22m[2m18 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T02:28:45.6561051Z packages/protocol test:  [32m✓[39m test/intents.test.ts [2m([22m[2m10 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T02:28:45.8385929Z packages/protocol test:  [32m✓[39m test/state.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T02:28:46.0014288Z packages/protocol test:  [32m✓[39m test/schema-shape.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:28:46.0066229Z packages/protocol test: [2m Test Files [22m [1m[32m4 passed[39m[22m[90m (4)[39m
2026-05-16T02:28:46.0079614Z packages/protocol test: [2m      Tests [22m [1m[32m36 passed[39m[22m[90m (36)[39m
2026-05-16T02:28:46.0081557Z packages/protocol test: [2m   Start at [22m 02:28:45
2026-05-16T02:28:46.0083359Z packages/protocol test: [2m   Duration [22m 874ms[2m (transform 117ms, setup 0ms, import 242ms, tests 37ms, environment 0ms)[22m
2026-05-16T02:28:46.0363277Z packages/protocol test: Done
2026-05-16T02:28:46.0370777Z apps/client test$ vitest run --exclude 'test/e2e/**'
2026-05-16T02:28:46.0375088Z apps/server test$ vitest run --exclude 'test/**/*.integ.test.ts'
2026-05-16T02:28:46.6110361Z apps/server test: [1m[30m[46m RUN [49m[39m[22m [36mv4.1.5 [39m[90m/home/runner/work/rebno/rebno/apps/server[39m
2026-05-16T02:28:46.6820381Z apps/client test: [1m[46m RUN [49m[22m [36mv3.2.4 [39m[90m/home/runner/work/rebno/rebno/apps/client[39m
2026-05-16T02:28:47.7588532Z apps/server test:  [32m✓[39m test/persistence.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 73[2mms[22m[39m
2026-05-16T02:28:48.1440244Z apps/server test:  [32m✓[39m test/rate-limit.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T02:28:48.6467736Z apps/server test:  [32m✓[39m test/layout-derive.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 115[2mms[22m[39m
2026-05-16T02:28:48.8901057Z apps/client test: [90mstderr[2m | src/__test__/game-scene.test.ts[2m > [22m[2mscenes/GameScene[2m > [22m[2mtest 5: onRoomLayout calls verifyRoomLayout first; render skipped on false
2026-05-16T02:28:48.8919961Z apps/client test: [22m[39mroom_layout signature did not verify — rendering anyway (defense-in-depth; see 06.1-D40-SPIKE.md) mvp-lobby 000
2026-05-16T02:28:48.9301955Z apps/server test:  [32m✓[39m test/room-key.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 28[2mms[22m[39m
2026-05-16T02:28:48.9813384Z apps/client test:  [32m✓[39m src/__test__/game-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 257[2mms[22m[39m
2026-05-16T02:28:49.2736977Z apps/server test: {"level":40,"time":1778898529265,"pid":3329,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T02:28:49.2837388Z apps/server test:  [32m✓[39m test/staging-invite.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 25[2mms[22m[39m
2026-05-16T02:28:49.2940194Z apps/server test: {"level":40,"time":1778898529273,"pid":3329,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T02:28:49.2959656Z apps/server test: {"level":40,"time":1778898529274,"pid":3329,"hostname":"runnervmrw5os","path":"/api/foo","msg":"staging_invite_rejected"}
2026-05-16T02:28:50.2736761Z apps/server test: {"level":30,"time":1778898530270,"pid":3360,"hostname":"runnervmrw5os","password":"[Redacted]","session_token":"[Redacted]","msg":"login"}
2026-05-16T02:28:50.2759799Z apps/server test:  [32m✓[39m test/otel-init.test.ts [2m([22m[2m4 tests[22m[2m)[22m[33m 690[2mms[22m[39m
2026-05-16T02:28:50.2779705Z apps/server test:      [33m[2m✓[22m[39m does not throw when OTEL_EXPORTER_OTLP_ENDPOINT is unset [33m 593[2mms[22m[39m
2026-05-16T02:28:50.3106562Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.teleport-gate.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 104[2mms[22m[39m
2026-05-16T02:28:51.2371089Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 1: fresh DB — migrate creates accounts table and records migration row
2026-05-16T02:28:51.2389471Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-QBFjWm/rebno.db
2026-05-16T02:28:51.2409223Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T02:28:51.2428653Z apps/server test: [run-migrations] OK
2026-05-16T02:28:51.2515166Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 2: pre-bootstrapped DB (Assumption A7) — reconcile seeds row before migrate runs
2026-05-16T02:28:51.2530129Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-gVOpFg/rebno.db
2026-05-16T02:28:51.2532168Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T02:28:51.2535395Z apps/server test: [run-migrations] reconciled __drizzle_migrations for pre-bootstrap DB (Assumption A7) — seeded 0001_baseline
2026-05-16T02:28:51.2539643Z apps/server test: [run-migrations] OK
2026-05-16T02:28:51.2615085Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T02:28:51.2634518Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-LMIh0m/rebno.db
2026-05-16T02:28:51.2659506Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T02:28:51.2663459Z apps/server test: [run-migrations] OK
2026-05-16T02:28:51.2700291Z apps/server test: [90mstdout[2m | test/run-migrations.test.ts[2m > [22m[2mrun-migrations.ts (Plan 12)[2m > [22m[2mScenario 3: idempotent second run — no error, no extra rows
2026-05-16T02:28:51.2719263Z apps/server test: [22m[39m[run-migrations] opening /tmp/rebno-migrate-test-LMIh0m/rebno.db
2026-05-16T02:28:51.2733587Z apps/server test: [run-migrations] migrationsFolder=/home/runner/work/rebno/rebno/packages/db/migrations
2026-05-16T02:28:51.2744483Z apps/server test: [run-migrations] OK
2026-05-16T02:28:51.2746182Z apps/server test:  [32m✓[39m test/run-migrations.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 58[2mms[22m[39m
2026-05-16T02:28:51.4697696Z apps/client test:  [32m✓[39m src/__test__/nameplate-stability.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 27[2mms[22m[39m
2026-05-16T02:28:51.5781078Z apps/server test:  [32m✓[39m test/log.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 20[2mms[22m[39m
2026-05-16T02:28:51.8792214Z apps/server test:  [32m✓[39m test/admin-stubs.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 9[2mms[22m[39m
2026-05-16T02:28:52.2041586Z apps/server test:  [32m✓[39m test/legacy-login.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 17[2mms[22m[39m
2026-05-16T02:28:52.4345680Z apps/server test:  [32m✓[39m test/health.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T02:28:52.6674687Z apps/client test:  [32m✓[39m src/__test__/nameplate.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 68[2mms[22m[39m
2026-05-16T02:28:53.3220752Z apps/server test: [90mstdout[2m | test/tick-accumulator.test.ts
2026-05-16T02:28:53.3225948Z apps/server test: [22m[39m◇ injected env (50) from ../../../../../../../etc/environment // tip: ⌘ override existing { override: true }
2026-05-16T02:28:53.3394565Z apps/server test: ℹ️  optional .env file not found: .env.test, .env
2026-05-16T02:28:53.8414248Z apps/client test:  [32m✓[39m src/__test__/sprite-state-machine.test.ts [2m([22m[2m29 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T02:28:54.1721314Z apps/server test:  [32m✓[39m test/tick-accumulator.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T02:28:54.1750497Z apps/server test: [2m Test Files [22m [1m[32m12 passed[39m[22m[90m (12)[39m
2026-05-16T02:28:54.2020904Z apps/server test: [2m      Tests [22m [1m[32m70 passed[39m[22m[90m (70)[39m
2026-05-16T02:28:54.2049144Z apps/server test: [2m   Start at [22m 02:28:46
2026-05-16T02:28:54.2081331Z apps/server test: [2m   Duration [22m 7.51s[2m (transform 581ms, setup 0ms, import 3.59s, tests 1.07s, environment 2ms)[22m
2026-05-16T02:28:54.2106238Z apps/server test: Done
2026-05-16T02:28:54.6765479Z apps/client test:  [32m✓[39m src/__test__/login-scene.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 12[2mms[22m[39m
2026-05-16T02:28:55.4286425Z apps/client test:  [32m✓[39m src/__test__/colyseus-client.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 11[2mms[22m[39m
2026-05-16T02:28:56.1381120Z apps/client test:  [32m✓[39m src/__test__/player-renderer.teleport.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 15[2mms[22m[39m
2026-05-16T02:28:56.8692138Z apps/client test:  [32m✓[39m src/__test__/player-renderer-spawn-delay.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 21[2mms[22m[39m
2026-05-16T02:28:57.5770884Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher.test.ts [2m([22m[2m12 tests[22m[2m)[22m[32m 16[2mms[22m[39m
2026-05-16T02:28:58.3343716Z apps/client test:  [32m✓[39m src/__test__/reconnect.test.ts [2m([22m[2m13 tests[22m[2m)[22m[32m 77[2mms[22m[39m
2026-05-16T02:28:59.1190279Z apps/client test:  [32m✓[39m src/__test__/chat-hud.test.ts [2m([22m[2m9 tests[22m[2m)[22m[32m 88[2mms[22m[39m
2026-05-16T02:28:59.8517905Z apps/client test:  [32m✓[39m src/__test__/nameplate-color.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 35[2mms[22m[39m
2026-05-16T02:29:00.5610766Z apps/client test:  [32m✓[39m src/__test__/reconciler.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T02:29:01.2630871Z apps/client test:  [32m✓[39m src/__test__/room-renderer.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T02:29:02.0263895Z apps/client test:  [32m✓[39m src/__test__/force-reset-overlay.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 84[2mms[22m[39m
2026-05-16T02:29:02.8101894Z apps/client test:  [32m✓[39m src/__test__/esc-menu.test.ts [2m([22m[2m8 tests[22m[2m)[22m[32m 81[2mms[22m[39m
2026-05-16T02:29:03.5261839Z apps/client test:  [32m✓[39m src/__test__/prediction.test.ts [2m([22m[2m6 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:29:04.2894642Z apps/client test:  [32m✓[39m src/__test__/background-renderer.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 81[2mms[22m[39m
2026-05-16T02:29:05.0003331Z apps/client test:  [32m✓[39m src/__test__/extrapolation.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T02:29:05.6942626Z apps/client test:  [32m✓[39m src/__test__/sprite-state-rate.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T02:29:06.3962755Z apps/client test:  [32m✓[39m src/__test__/room-layout-verify.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 10[2mms[22m[39m
2026-05-16T02:29:07.0877841Z apps/client test:  [32m✓[39m src/__test__/input-dispatcher-shift.test.ts [2m([22m[2m3 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T02:29:07.7965684Z apps/client test:  [32m✓[39m src/__test__/boot-font-gate.test.ts [2m([22m[2m2 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T02:29:08.5128607Z apps/client test:  [32m✓[39m src/__test__/auth-client.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 7[2mms[22m[39m
2026-05-16T02:29:09.2223173Z apps/client test:  [32m✓[39m src/__test__/room-collision-bottom-edge.test.ts [2m([22m[2m5 tests[22m[2m)[22m[32m 6[2mms[22m[39m
2026-05-16T02:29:09.9163247Z apps/client test:  [32m✓[39m src/__test__/depth-set.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T02:29:10.6132526Z apps/client test:  [32m✓[39m src/__test__/legacy-origin.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 4[2mms[22m[39m
2026-05-16T02:29:11.3064653Z apps/client test:  [32m✓[39m src/__test__/atlas-loader.test.ts [2m([22m[2m4 tests[22m[2m)[22m[32m 8[2mms[22m[39m
2026-05-16T02:29:11.9850249Z apps/client test:  [32m✓[39m src/__test__/protocol-version-check.test.ts [2m([22m[2m7 tests[22m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T02:29:12.6814521Z apps/client test:  [32m✓[39m src/__test__/env.test.ts [2m([22m[2m5 tests[22m[2m | [22m[33m4 skipped[39m[2m)[22m[32m 5[2mms[22m[39m
2026-05-16T02:29:12.7027780Z apps/client test: [2m Test Files [22m [1m[32m31 passed[39m[22m[90m (31)[39m
2026-05-16T02:29:12.7031634Z apps/client test: [2m      Tests [22m [1m[32m213 passed[39m[22m[2m | [22m[90m4 todo[39m[90m (217)[39m
2026-05-16T02:29:12.7033632Z apps/client test: [2m   Start at [22m 02:28:46
2026-05-16T02:29:12.7035486Z apps/client test: [2m   Duration [22m 26.02s[2m (transform 938ms, setup 69ms, collect 1.68s, tests 1.08s, environment 14.99s, prepare 3.01s)[22m
2026-05-16T02:29:12.8396571Z apps/client test: Done
2026-05-16T02:29:12.8492156Z 
2026-05-16T02:29:12.8492753Z verify-phase-4: OK (12 steps green)
